﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;

using Xc.DataAccess.Core;
using Xc.DataAccess.DataBase.DeviceInfos.Models;
using System.Data;

namespace Xc.DataAccess.DataBase.DeviceInfos
{
    /// <summary>
    /// 设备属性信息服务
    /// </summary>
    /// <typeparam name="TDbContext"></typeparam>
    public class DbDeviceInfoPropertyService<TDbContext> : IDbDeviceInfoPropertyService where TDbContext : DbContext, IDbDeviceInfo
    {
        private readonly IDbContextFactory<TDbContext> _dbContextFactory;

        public DbDeviceInfoPropertyService(IDbContextFactory<TDbContext> dbContextFactory)
        {
            _dbContextFactory = dbContextFactory;
        }
        /// <summary>
        /// 设置属性值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public Result SetProperty(string name, string value, string deviceId)
        {
            using var db = _dbContextFactory.CreateDbContext();
            var device = db.DeviceInfos.Find(deviceId);
            if (device == null)
            {
                return Result.Reject("不存在这样的设备编号");
            }
            var property = db.PropertyInfos.Where(p => p.DeviceInfoId == deviceId).FirstOrDefault();
            if (property == null)
            {
                db.PropertyInfos.Add(new PropertyInfo { DeviceInfoId = deviceId, Name = name, Value = value });
            }
            else
            {
                property.Value = value;
            }
            db.PropertyInfoHistorys.Add(new PropertyInfoHistory { DateTimeCreate = DateTime.Now, DeviceInfoId = deviceId, Value = value, Name = name });
            return Result.From(db.SaveChanges(), (s) => s > 1);
        }
        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="deviceid"></param>
        /// <returns></returns>
        public ResultData<PropertyInfo[]> GetProperties(string deviceid)
        {
            using var db = _dbContextFactory.CreateDbContext();
            var properties = db.PropertyInfos.Where(p => p.DeviceInfoId == deviceid);
            return ResultData<PropertyInfo[]>.Accept("获取成功", properties.ToArray());
        }
        /// <summary>
        /// 获取历史属性信息
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="dateTimeStart"></param>
        /// <param name="dateTimeEnd"></param>
        /// <returns></returns>
        public IQueryable<PropertyInfoHistory> GetProperties(string deviceId, DateTime? dateTimeStart, DateTime? dateTimeEnd)
        {
            using var db = _dbContextFactory.CreateDbContext();
            var properties = db.PropertyInfoHistorys.Where(p => p.DeviceInfoId == deviceId);
            if (dateTimeStart.HasValue)
            {
                properties = properties.Where(p => p.DateTimeCreate > dateTimeStart);
            }
            if (dateTimeEnd.HasValue)
            {
                properties = properties.Where(p => p.DateTimeCreate <= dateTimeEnd);
            }
            return properties;
        }
        /// <summary>
        /// 获取属性表
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="dateTimeStart"></param>
        /// <param name="dateTimeEnd"></param>
        /// <returns></returns>
        public async Task<DataTable> GetPropertiesTable(string deviceId, DateTime? dateTimeStart, DateTime? dateTimeEnd)
        {
            var datas = await GetProperties(deviceId, dateTimeStart, dateTimeEnd).ToArrayAsync();
            var columns = datas.Select(p => p.Name).GroupBy(p => p).Select(p => p.Key).ToArray();
            var infos = datas.GroupBy(p => p.DateTimeCreate.Day).Select(p => new { Day = p.Key, Data = p.ToArray() });
            DataTable dataTable = new DataTable();
            dataTable.Columns.AddRange(columns.Select(p => new DataColumn(p)).ToArray());
            foreach (var item in infos)
            {
                var row = dataTable.NewRow();
                List<string> vs = new List<string>();
                foreach (var pro in columns)
                {
                    var result = item.Data.Where(p => p.Name == pro).FirstOrDefault();
                    if (result != null)
                    {
                        vs.Add(result.Value);
                    }
                    else
                    {
                        vs.Add(string.Empty);
                    }
                }
                row.ItemArray = vs.ToArray();
                dataTable.Rows.Add(row);
            }
            return dataTable;
        }
    }
}
